from fastapi import APIRouter, Cookie, Query, status, HTTPException

from typing import Annotated, Optional

from datetime import datetime

from src.weather_service.services.weather import Weather_service
from src.weather_service.services.search_weather import Search_service
from src.weather_service.schemas_weather import (
    Upload_weather,
    Update_weather
)

weather_router = APIRouter(prefix="/region/weather", tags=["weather"])


def validate_datetime(dt: Optional[str]):
    if dt is None:
        return None
    try:
        dt = datetime.fromisoformat(dt)
    except Exception:
        raise HTTPException(status_code=400, detail="bad datetime")
    return dt


@weather_router.get(
    "/search",
    status_code=status.HTTP_200_OK
)
async def search_weather(
    startDateTime: Optional[str] = None,
    endDateTime: Optional[str] = None,
    regionId: Optional[int] = None,
    weatherCondition: Optional[str] = None,
    from_var: Annotated[int | None, Query(alias="from")] = 0,
    size: Optional[int] = 10,
    id: Annotated[int | None, Cookie()] = None
):
    if (
        (regionId <= 0) or
        (not (from_var is None) and from_var < 0) or
        (not (size is None) and size <= 0)
    ):
        raise HTTPException(status_code=400, detail="bad data")

    if from_var is None:
        from_var = 0
    if size is None:
        size = 10

    if startDateTime:
        startDateTime = validate_datetime(startDateTime)
    if endDateTime:
        endDateTime = validate_datetime(endDateTime)

    return await Search_service().search_weather(
        startDateTime=startDateTime,
        endDateTime=endDateTime,
        regionId=regionId,
        weatherCondition=weatherCondition,
        from_var=from_var,
        size=size,
        user_id=id
    )


@weather_router.post(
    "",
    # response_model=,
    status_code=status.HTTP_201_CREATED
)
async def create_weather(
    payload: Upload_weather,
    id: Annotated[int | None, Cookie()] = None
):
    return await Weather_service().create_weather(
        payload,
        user_id=id
    )


@weather_router.get(
    "/{regionId}",
    # response_model=,
    status_code=status.HTTP_200_OK
)
async def get_all_weather(
    regionId: Optional[int],
    id: Annotated[int | None, Cookie()] = None
):
    if regionId is None or regionId <= 0:
        raise HTTPException(status_code=400, detail="bad data")

    return await Weather_service().get_all_weather(
        regionId,
        user_id=id
    )


@weather_router.put(
    "/{regionId}",
    # response_model=,
    status_code=status.HTTP_200_OK
)
async def edit_weather(
    regionId: int,
    payload: Update_weather,
    id: Annotated[int | None, Cookie()] = None
):
    if regionId is None:
        raise HTTPException(status_code=400, detail="bad data")

    return await Weather_service().edit_weather(
        regionId,
        payload,
        user_id=id
    )


@weather_router.delete(
    "/{regionId}",
    status_code=status.HTTP_200_OK
)
async def delete_all_weather(
    regionId: int,
    id: Annotated[int | None, Cookie()] = None
):
    if regionId is None or regionId <= 0:
        raise HTTPException(status_code=400, detail="bad data")

    return await Weather_service().delete_all_weather(
        regionId,
        user_id=id
    )
